package com.retail.order.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;


/**
 * @Author: 靳家振
 * @Date: 2023/11/24 14:02
 * @Description:
 **/

@Configuration
public class RabbitMQConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {
    public static final String INSERT_QUEUE = "insertQueue";
    public static final String INSERT_EXCHANGE = "insertExchange";
    public static final String INSERT_KEY = "insertKey";

    public static final Logger logger = LoggerFactory.getLogger (RabbitMQConfig.class);

    private RabbitTemplate rabbitTemplate;

    @Primary
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate (connectionFactory);
        this.rabbitTemplate = rabbitTemplate;
        rabbitTemplate.setMessageConverter (messageConverter ());
        rabbitTemplate ();
        return rabbitTemplate;
    }

    //@PostConstruct
    public void rabbitTemplate() {
        rabbitTemplate.setConfirmCallback (this);
        rabbitTemplate.setReturnsCallback (this);
    }

    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter ();
    }

    @Bean
    public Queue queue() {
        return new Queue (INSERT_QUEUE, true);
    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange (INSERT_EXCHANGE);
    }


    @Bean
    public Binding binding() {
        return BindingBuilder.bind (queue ()).to (directExchange ()).with (INSERT_KEY);
    }


    /*
    confirm方法在消息被RabbitMQ确认时调用，参数correlationData是消息的相关数据，b是是否被确认，s是额外的字符串信息。
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        logger.info ("{}消息到达交换机", correlationData.getId ());
    }

    /*
    returnedMessage方法在消息返回时调用，参数returnedMessage是返回的消息对象，你可以通过它获取消息的详细信息。
     */
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        logger.info ("{}消息丢失", returnedMessage.getMessage ().getMessageProperties ().getMessageId ());
    }
}
